#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#define handle_error(cmd, result) \
    if(result < 0)                \
    {                             \
        perror(cmd);              \
        return -1;                \
    }                             

int main(int argc, char const *argv[])
{
    // 使用udp协议完成客户端和服务端的通信
    // EOF作为关闭的信号
     struct sockaddr_in server_addr, client_addr;
    // 清空
    memset(&server_addr, 0, sizeof(server_addr));
    memset(&client_addr, 0, sizeof(client_addr));
    // 填写服务端地址
    server_addr.sin_family = AF_INET;
    // 填写ip地址 0.0.0.0
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr.s_addr);
    // 填写端口号
    server_addr.sin_port = htons(6666);
    // udp编成流程
    // 1.socket
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    handle_error("socket", sockfd);
    // 2.服务端绑定地址
    socklen_t server_len = sizeof(server_addr);
    socklen_t client_len = sizeof(client_addr);
    int bind_R = bind(sockfd, (struct sockaddr*)&server_addr, server_len);
    handle_error("bind", bind_R);
    // 直接可以收发数据
    char* buf = malloc(sizeof(char) * 1024);
    do
    {
        // 接收到数据存到缓冲
        memset(buf, 0 ,1024);
        int recvfrom_R = recvfrom(sockfd, buf, 1024, 0, (struct sockaddr*)&client_addr, &client_len);
        handle_error("recvfrom", recvfrom_R);
        if (strncmp(buf, "EOF", 3) != 0)
        {
            printf("接收到客户端信息%s %d信息:%s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buf);
            strcpy(buf, "OK\n");
        }
        else
        {
            printf("收到结束信息，准备关闭\n");
        }
        // 回复数据
        int sento_R = sendto(sockfd, buf, 4, 0, (struct sockaddr*)&client_addr, client_len);
        handle_error("sendto", sento_R);
    }   
    while (strncmp(buf, "EOF", 3) != 0);
    
    free(buf);
    return 0;
}
